/**
 * A React component to view a PDF document
 *
 * @see https://react-pdf-viewer.dev
 * @license https://react-pdf-viewer.dev/license
 * @copyright 2019-2024 Nguyen Huu Phuoc <me@phuoc.ng>
 */

'use client';

import * as React from 'react';
import { DefaultLocalization, LocalizationContext } from './localization/LocalizationContext';
import { TextDirection, ThemeContext, ThemeContextProps } from './theme/ThemeContext';
import { withTheme } from './theme/withTheme';
import { type LocalizationMap } from './types/LocalizationMap';
import { type PdfJsApiProvider } from './types/PdfJsApiProvider';
import { PdfJsApiContext } from './vendors/PdfJsApiContext';

export interface ThemeProps {
    direction?: TextDirection;
    theme?: string;
}

const STYLE_ID = '___rpv-styles___';

export const Provider: React.FC<{
    children?: React.ReactNode;
    localization?: LocalizationMap;
    pdfApiProvider: PdfJsApiProvider;
    // Theme
    theme?: string | ThemeProps;
    workerUrl: string;
}> = ({
    children,
    localization,
    pdfApiProvider,
    theme = {
        direction: TextDirection.LeftToRight,
        theme: 'light',
    },
    workerUrl,
}) => {
    pdfApiProvider.GlobalWorkerOptions.workerSrc = workerUrl;

    // Locale context
    const [l10n, setL10n] = React.useState(localization || DefaultLocalization);
    const localizationContext = { l10n, setL10n };
    React.useEffect(() => {
        if (localization) {
            setL10n(localization);
        }
    }, [localization]);

    // Theme context
    const themeProps = typeof theme === 'string' ? { direction: TextDirection.LeftToRight, theme } : theme;
    const themeStr = themeProps.theme || 'light';
    const [currentTheme, setCurrentTheme] = withTheme(themeStr);
    const themeContext: ThemeContextProps = Object.assign(
        {},
        {
            currentTheme,
            direction: themeProps.direction,
            setCurrentTheme,
        },
    );

    React.useInsertionEffect(() => {
        let styleEle = document.head.querySelector(`style[id=${STYLE_ID}]`);
        if (!styleEle) {
            styleEle = document.createElement('style');
            styleEle.setAttribute('id', STYLE_ID);
            document.head.appendChild(styleEle);

            // Override the styles of hidden canvas element generated by pdf-js
            styleEle.textContent = `
.hiddenCanvasElement {
    display: none;
    opacity: 0;
}`;
        }

        return () => {
            document.head.removeChild(styleEle);
        };
    }, []);

    return (
        <PdfJsApiContext.Provider value={{ pdfJsApiProvider: pdfApiProvider }}>
            <LocalizationContext.Provider value={localizationContext}>
                <ThemeContext.Provider value={themeContext}>{children}</ThemeContext.Provider>
            </LocalizationContext.Provider>
        </PdfJsApiContext.Provider>
    );
};
